package com.josework.springhelloworld.entity;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.Comparator;
import java.util.concurrent.Callable;
import java.util.function.*;

/**
 *
 * 组合也是提高类的复用性。如果想让类具有更多的扩展功能，多用组合，少用继承
 */
@Data
@AllArgsConstructor
public class SoccerPlayer {
    private String name;
//    private Soccer soccer;

    //打开一个资源，只能读取文件的第一行。
    public static String processFile() throws IOException{
        try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))){
            return br.readLine();
        }
    }

    public static String processFile2(BufferedReaderProcessor p) throws IOException{
        try(BufferedReader b = new BufferedReader(new FileReader("data.txt"))){
           return p.process(b);
        }
    }

    public static <T> void forEach(List<T> list, Consumer<T> c){
        for (T t : list) {
            c.accept(t);
        }
    }

    public static <T, R> List<R> map (List<T> list, Function<? super T, R> f){
        List<R> res = new ArrayList<>();
        for (T s : list) {
            res.add(f.apply(s));
        }
        return res;

    }

    public static <T> List<T> filter(List<T> list, Predicate<T> p){
        List<T> res = new ArrayList<T>();
        for (T t : list) {
            if (p.test(t)){
                res.add(t);
            }
        }
        return res;
    }



    public static void main(String[] args) throws IOException {

        List<SoccerPlayer> list = new ArrayList<>();
        list.add(new SoccerPlayer("xiaoming"));
        list.add(new SoccerPlayer("xiaohong"));
        list.add(new SoccerPlayer("xiao"));
//        for (SoccerPlayer soccerPlayer : list) {
//            soccerPlayer.setName("Hello "+soccerPlayer.getName());
//        }

//        String oneLine = processFile2((BufferedReader br) -> br.readLine());
//        String twoLine = processFile2((BufferedReader br) -> br.readLine()+br.readLine());

        forEach(list,(s) -> {
            System.out.println(s.getName());
        });
        Collections.sort(list, Comparator.comparingInt((SoccerPlayer i)-> i.getName().length()));
        List<Integer> l = map(Arrays.asList("lambds", "in", "action"), String::length);
        List<Integer> integers = map(list, i -> i.getName().length());
        Function<BufferedReader,String> f = (BufferedReader br) -> {
            try {
               return br.readLine();
            } catch (IOException e) {
                throw  new RuntimeException(e);
            }
        };

        // 类型检查过程
        // 1. filter的定义 filter(List<SoccerPlayer>, Predicate<SoccerPlayer> p)
        // 2. Predicate<SoccerPlayer> 接口的抽象方法又是什么呢？ -> boolean test(SoccerPlayer s)
        // 3. test方法接受一个SoccerPlayer并返回一个 boolean
        // 4.
        List<SoccerPlayer> filterLengthThan5 = filter(list, i -> i.getName().length() > 5);







        //1. 编译器如何对Lambda做类型检查？

        //2. Lambda在自身内部引用局部变量，还有和Void兼容的Lambda








    }
}